package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.schedule.IScheduleClient;
import com.heima.common.constants.WmNewsMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.enums.AppHttpCodeEnum;
import com.heima.model.schedule.dtos.Task;
import com.heima.model.wemedia.dtos.WmNewsDownOrUpDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsQueryDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.common.ProtostuffUtil;
import com.heima.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;

import com.heima.wemedia.service.WmNewsAutoScanService;

import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;

import com.heima.wemedia.service.WmNewsTaskService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Autowired(required = false)
    WmMaterialMapper wmMaterialMapper;

    @Autowired(required = false)
    WmNewsMaterialService wmNewsMaterialService;
    @Autowired
    WmNewsAutoScanService wmNewsAutoScanService;

    @Autowired
    WmNewsTaskService wmNewsTaskService;

    @Autowired
    KafkaTemplate<String,String> kafkaTemplate;


    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //校验参数
        if(dto.getTitle()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "标题不能为空");
        }
        //更新数据库
        WmNews wmNews = insertOrUpdate(dto);
        if(wmNews.getStatus()==0){
            return ResponseResult.okResult(null);
        }
        //删除中间表数据
        delNewsMaterial(wmNews.getId());
        //添加中间表数据
        addNewsMaterial(wmNews,dto);
        //wmNewsAutoScanService.autoScanWmNews(wmNews.getId());
        wmNewsTaskService.addNewsToTask(wmNews.getId(),dto.getPublishTime());
        return ResponseResult.okResult(null);
    }

    /**
     * 分页查询wmNews
     * @param dto
     * @return
     */
    @Override
    public ResponseResult listPage(WmNewsQueryDto dto) {
        Page page = new Page(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> wrapper = Wrappers.<WmNews>lambdaQuery()
                .eq(WmNews::getUserId, WmThreadLocalUtil.getThreadLocal().getId());
        if(dto.getKeyword()!=null){
            wrapper.like(WmNews::getTitle,dto.getKeyword());
        }
        if(dto.getBeginPubdate()!=null&&dto.getEndPubdate()!=null){
            wrapper.between(WmNews::getPublishTime,dto.getBeginPubdate(),dto.getEndPubdate());
        }
        if(dto.getStatus()!=null){
            wrapper.eq(WmNews::getStatus,dto.getStatus());
        }
        if(dto.getChannelId()!=null){
            wrapper.eq(WmNews::getChannelId, dto.getChannelId());
        }

        PageResponseResult pageResponseResult = new PageResponseResult();
        baseMapper.selectPage(page, wrapper);
        pageResponseResult.setCurrentPage((int) page.getCurrent());
        pageResponseResult.setSize((int) page.getSize());
        pageResponseResult.setTotal((int) page.getTotal());
        pageResponseResult.setData(page.getRecords());

        return pageResponseResult;
    }

    @Override
    public ResponseResult getOneNews(Integer id) {
        WmNews wmNews = baseMapper.selectOne(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getId, id));
        return ResponseResult.okResult(wmNews);
    }

    @Override
    @Transactional
    public ResponseResult delNewsById(Integer id) {
        WmNews wmNews = baseMapper.selectById(id);
        if(WmNews.Status.PUBLISHED.getCode()==wmNews.getStatus()){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "该文章已经发布请先下架才可以删除");
        }
        wmNewsMaterialService.remove(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id));
        baseMapper.deleteById(id);
        return ResponseResult.okResult(null);
    }

    @Override
    public ResponseResult downOrUp(WmNewsDownOrUpDto dto) {
        if(dto==null&&dto.getEnable()==null&&dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "参数有误");
        }
        WmNews wmNews = baseMapper.selectById(dto.getId());
        if(WmNews.Status.PUBLISHED.getCode()!=wmNews.getStatus()){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "此文章不是发布状态");
        }
        if(dto.getEnable()>-1&&dto.getEnable()<2){
            wmNews.setEnable(dto.getEnable());
            baseMapper.updateById(wmNews);
        }
        //将消息存入kafka中
        if(wmNews.getArticleId()!=null){
            Map<String, Object> map = new HashMap<>();
            map.put("articleId",wmNews.getArticleId());
            map.put("enable",dto.getEnable());
            kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(map));
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 根据封面类型插入中间表数据更新 新闻表
     * @param wmNews
     * @param dto
     */
    private void addNewsMaterial(WmNews wmNews,WmNewsDto dto) {
        //获取封面图片
        //List<String> coverImages=
        //需要存入的封面图片
        List<String> collect=dto.getImages();
        //自动
        if(wmNews.getType()==null){
            collect = getContentForImages(wmNews);
            //coverImages=contentForImages;
            if(collect.size()>0&&collect.size()<3){
                collect.stream().limit(1).collect(Collectors.toList());
                wmNews.setType((short) 1);
            }
            if(collect.size()>=3){
                collect.stream().limit(3).collect(Collectors.toList());
                wmNews.setType((short) 3);
            }else {
                wmNews.setType((short) 0);
            }
        }
        wmNews.setImages(StringUtils.join(collect, ","));
        if(collect.size()>0){
            //图片id集合
            List<Integer> list = getImagesId(collect);
            ArrayList<WmNewsMaterial> wmNewsMaterialArrayList = new ArrayList<>();
            list.forEach(item->{
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();

                wmNewsMaterial.setMaterialId(item);
                wmNewsMaterial.setNewsId(wmNews.getId());
                wmNewsMaterial.setType((short) 1);
                wmNewsMaterial.setOrd((short) 0);
                wmNewsMaterialArrayList.add(wmNewsMaterial);
            });
            wmNewsMaterialService.saveBatch(wmNewsMaterialArrayList);
        }
        updateById(wmNews);
    }

    private void delNewsMaterial(Integer id) {
        List<Integer> collect = wmNewsMaterialService.list(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id)).stream().map(WmNewsMaterial::getId).collect(Collectors.toList());
        wmNewsMaterialService.removeByIds(collect);
    }

    /**
     * 保存
     * @param dto
     */
    private WmNews insertOrUpdate(WmNewsDto dto) {
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        wmNews.setSubmitedTime(new Date());
        wmNews.setUserId(WmThreadLocalUtil.getThreadLocal().getId());
        List<String> images = dto.getImages();
        if(images!=null&&images.size()!=0){
            String imagesStr = StringUtils.join(images, ",");
            wmNews.setImages(imagesStr);
        }
        if(wmNews.getType()==-1){
            wmNews.setType(null);
        }
        if(wmNews.getId()==null){
            //插入数据库
            baseMapper.insert(wmNews);
        }else {
            //更新数据库
            baseMapper.updateById(wmNews);
        }
        return wmNews;
    }




    /**
     * 根据url集合查询出id集合
     * @param contentForImages
     * @return
     */
    private List<Integer> getImagesId(List<String> contentForImages) {
        List<Integer> collect = wmMaterialMapper.selectList(Wrappers.
                <WmMaterial>lambdaQuery().in(WmMaterial::getUrl, contentForImages))
                .stream().map(WmMaterial::getId).collect(Collectors.toList());
        return collect;
    }

    /**
     * 将内容中的图片取出来存放在list集合中
     * @param wmNews
     * @return
     */
    private List<String> getContentForImages(WmNews wmNews) {

        List<String> list = new ArrayList<>();
        List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
        for (Map map : maps) {
            if(map.get("type").equals("image")){
                list.add((String)map.get("value"));
            }
        }
        return list;
    }
}
